package com.xbongbong.paas.script.controller;

import com.alibaba.fastjson.JSON;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.pojo.dto.MenuSettingLocationDTO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.RoleService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.role.pojo.dto.RoleAppendOrDeleteDTO;
import com.xbongbong.pro.script.pojo.vo.ScriptVO;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.domain.entity.ProPermissionEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.ProPermissionModel;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * @ClassName MenuSettingScriptController
 * @Description 菜单设置脚本
 * @Author mengna.Deng
 * @Date 2021/11/15 10:16
 * @Version 1.0
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/script/menuSetting")
public class MenuSettingScriptController {
    private static final Logger LOG = LoggerFactory.getLogger(MenuSettingScriptController.class);
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private CompanyModel companyModel;
    @Resource
    private RoleService roleService;
    @Resource
    private ProPermissionModel proPermissionModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;


    /**
     * 在权限表里面追加/删除页面定制权限
     * @param menuSettingLocationDTO
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/appendOrDeleteCustomPagePermission", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String appendOrDeleteCustomPagePermission(@RequestBody @Valid MenuSettingLocationDTO menuSettingLocationDTO) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(menuSettingLocationDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }
        //遍历出有自定义的公司
        List<String> corpidList = menuSettingLocationDTO.getCorpidList();
        if (null == corpidList){
            corpidList = companyModel.getCorpidList();
        }
        // 是否是追加
        Integer operationType = menuSettingLocationDTO.getOperationType();
        Boolean isAppend = null == operationType || Objects.equals(operationType,0);
        //查出页面定制和菜单设置的permissionId
        ProPermissionEntity replacedPermissionEntity = proPermissionModel.getByAlias(StringConstant.MENU_SET);
        ProPermissionEntity replacePermissionEntity = proPermissionModel.getByAlias(ProPermissionAliasEnum.CUSTOM_PAGE.getAlias());
        if (null == replacedPermissionEntity || null == replacePermissionEntity){
            LOG.info("结束 fixMenuSettingLocation fail,页面定制或者菜单设置的permissionId为空");
            return JSON.toJSONString(new XbbResponse<>(new BaseVO()));
        }
        RoleAppendOrDeleteDTO roleAppendOrDeleteDTO = new RoleAppendOrDeleteDTO();
        if (isAppend){
            roleAppendOrDeleteDTO.setReplacedRoleId(replacedPermissionEntity.getId());
            roleAppendOrDeleteDTO.setReplaceRoleId(replacePermissionEntity.getId());
        }else {
            roleAppendOrDeleteDTO.setReplacedRoleId(replacePermissionEntity.getId());
            roleAppendOrDeleteDTO.setReplaceRoleId(-1);
        }

        Integer pageSize = 20;
        int corpidSize = corpidList.size();
        Integer pageNum = corpidSize / pageSize + 1;
        LOG.info("开始刷脚本："+corpidSize);
        for (int i = 1; i < pageNum + 1; i++) {
            Integer start = (i - 1) * pageSize;
            Integer end = i * pageSize;
            end = end > corpidSize ? corpidSize : end;
            List<String> subList = corpidList.subList(start,end);
            // 分页循环
            if (CollectionUtils.isNotEmpty(subList)){
                roleAppendOrDeleteDTO.setCorpidList(subList);
                roleService.batchAppendOrDeletePermissions(roleAppendOrDeleteDTO);
            }
        }
        LOG.info("结束 fixMenuSettingLocation success");
        return JSON.toJSONString(new XbbResponse<>(new BaseVO()));
    }


    @RequestMapping(value = "/setMenuWhiteList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String explains(@RequestBody @Valid MenuSettingLocationDTO settingLocationDTO, BindingResult br) throws XbbException {
        XbbResponse<ScriptVO> response;
        if ( br.hasErrors() ) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                if (!proBaseConfig.getXbbCode().equals(settingLocationDTO.getXbbCode())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }

                Set<String> updateCorpidList = new HashSet<>();
                List<String> businessRuleCorpid = settingLocationDTO.getCorpidList();
                CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.MENU_WHITE.getAlias(), "0");
                if (Objects.isNull(companyConfigEntity)) {
                    updateCorpidList.addAll(businessRuleCorpid);
                } else {
                    List<String> list = JSON.parseArray(companyConfigEntity.getConfigValue(), String.class);
                    if (Objects.equals(1, settingLocationDTO.getOperationType())) {
                        list.removeAll(businessRuleCorpid);
                    } else {
                        list.addAll(businessRuleCorpid);
                    }
                    updateCorpidList.addAll(list);
                }
                companyConfigModel.save("0", CompanyConfigEnum.MENU_WHITE.getAlias(), CompanyConfigEnum.MENU_WHITE.getName(), JSON.toJSONString(updateCorpidList));
                paasRedisHelper.setValue(RedisPrefixConstant.MENU_WHITE_LIST,"0", JSON.toJSONString(updateCorpidList), TimeConstant.SECONDS_PER_DAY);
                ScriptVO scriptVO = new ScriptVO();
                response = new XbbResponse<>(scriptVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

}
